<?php
/**
 *	FILENAME: 		/libraries/newswire.php
 *	DESCRIPTION:	This library that uses the PHP Snoopy library to obtain and parse the Wildcat Newswire.
 *	AUTHOR:			Casey Burkhardt
 *	VERSION:		1.0.0
 *	LAST MODIFIED:	1/5/2010
 **/

require_once($_SERVER['DOCUMENT_ROOT'] . "/config/environment.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/libraries/Snoopy.class.php");

// Define Constants
global $NEWSWIRE_URL, $HEADER_DATA;
$NEWSWIRE_URL = "http://unit.villanova.edu/mobile/newswire/wildcatnewswire/undergrad.html";
$HEADER_DATA = getHTTPRequestHeaders();

/**
 *	DESCRIPTION:	Obtains the timestamp of the current issue of the Wildcat Newswire
 **/
function getNewswireTimestamp() {
    global $NEWSWIRE_URL, $HEADER_DATA;

    // We start by fetching the page containing the current issue of the Wildcat Newswire.
    // Create a new instance of Snoopy, the page fetching / parsing engine.
    $newswire = new Snoopy;

    // We can set a timeout, in case this thing doesn't work, but the Newswire server is unreliable, so we'll leave it be for now.
    // TODO: Determine if we need a timeout set here.
    //	$loginPage -> read_timeout = 5;

    // Set up appropriate HTTP header data.
    $newswire -> rawheaders = $HEADER_DATA;

    if ($newswire -> fetch($NEWSWIRE_URL)) {
        $searchQueryStart = "<td><i>Created: ";
        $searchQueryEnd = "</i></td>";
        $startIndex = strpos($newswire -> results, $searchQueryStart) + strlen($searchQueryStart);
        if ($startIndex === FALSE) {
            // The timestamp value could not be located on the page.
            return FALSE;
        } else {
            $endIndex = strpos($newswire -> results, $searchQueryEnd, $startIndex);
            $timestamp = trim(substr($newswire -> results, $startIndex, $endIndex - $startIndex));
            return $timestamp;
        }
    } else {
        // Downloading the remote page failed, return FALSE.
        return FALSE;
    }
}

/**
 *	DESCRIPTION:	Returns an array of all sections in the current Wildcat Newswire.
 **/
function getNewswireSections() {
    global $NEWSWIRE_URL, $HEADER_DATA;

    // Set up Snoopy with the required parameters.
    $newswire = new Snoopy;
    $newswire -> rawheaders = $HEADER_DATA;

    if ($newswire -> fetch($NEWSWIRE_URL)) {
        // In order to obtain the section names, we'll extract all the text within '<b>' HTML tags.
        $headingTexts = array();
        $searchQueryStart = "<b>";
        $searchQueryEnd = "</b>";
        $startIndex = strpos($newswire -> results, $searchQueryStart);
        while ($startIndex !== FALSE) {
            $startIndex = $startIndex + strlen($searchQueryStart);
            $endIndex = strpos($newswire -> results, $searchQueryEnd, $startIndex);
            $headingTexts[] = trim(substr($newswire -> results, $startIndex, $endIndex - $startIndex));
            $startIndex = strpos($newswire -> results, $searchQueryStart, $endIndex + strlen($searchQueryEnd));
        }
    } else {
        // Downloading the remote page failed, return FALSE.
        return FALSE;
    }

    // We can now process the text in '<b>' HTML tags and determine which are section titles.
    if (count($headingTexts) === 0) {
        return FALSE;
    }

    // The first item in the array will repeat, one we find the first repetition, we know we've enumerated all the sections.
    $firstRepeat = FALSE;
    for($i = 1; $i < count($headingTexts); $i++) {
        if ($headingTexts[0] == $headingTexts[$i]) {
            $firstRepeat = $i;
            break;
        }
    }

    // Verify that we found a duplicate and slice the array of results.
    if ($firstRepeat === 0 || $firstRepeat === FALSE || $firstRepeat === (count($headingTexts) - 1)) {
        return FALSE;
    } else {
        $sections = array_slice($headingTexts, 0, $firstRepeat);
    }
    return $sections;
}

/**
 *	DESCRIPTION:	Returns an array of story titles and their story ID values from the current Wildcat Newswire given a section name.
 **/
function getStoryData($sectionName) {
    global $NEWSWIRE_URL, $HEADER_DATA;

    // Set up Snoopy with the required parameters.
    $newswire = new Snoopy;
    $newswire -> rawheaders = $HEADER_DATA;

    if ($newswire -> fetch($NEWSWIRE_URL)) {
        if(strlen($sectionName) == 0) {
            // List all stories.
            $sectionName = strtoupper($sectionName);
            $searchQueryStart = '<div class="type">';
            $searchQueryEnd = '<a name="0"></a>';
            $startIndex = strpos($newswire -> results, $searchQueryStart) + strlen($searchQueryStart);
            if ($startIndex === FALSE) {
                // Section heading could not be found on the fetched page.
                return FALSE;
            } else {
                $endIndex = strpos($newswire -> results, $searchQueryEnd, $startIndex);
                $dataBlock = trim(substr($newswire -> results, $startIndex, $endIndex - $startIndex));
            }
        } else {
            // List only stories within the section heading.
            $sectionName = strtoupper($sectionName);
            $searchQueryStart = $sectionName;
            $searchQueryEnd = '<div class="type">';
            $startIndex = strpos($newswire -> results, $searchQueryStart) + strlen($searchQueryStart);
            if ($startIndex === FALSE) {
                // Section heading could not be found on the fetched page.
                return FALSE;
            } else {
                $endIndex = strpos($newswire -> results, $searchQueryEnd, $startIndex);
                $dataBlock = trim(substr($newswire -> results, $startIndex, $endIndex - $startIndex));
            }
        }
    } else {
        // Downloading the remote page failed, return FALSE.
        return FALSE;
    }

    // Begin parsing the results to extract story titles and story IDs.
    $storyData = array();
    $searchQueryStart = '<a href="#';
    $searchQueryEnd = '" target="_self">';
    $searchQueryTitleEnd = '</a>';
    $startIndex = strpos($dataBlock, $searchQueryStart);
    while ($startIndex !== FALSE) {
        // Search through the data block and extract the ID of a story.
        $startIndex = $startIndex + strlen($searchQueryStart);
        $endIndex = strpos($dataBlock, $searchQueryEnd, $startIndex);
        if ($endIndex === FALSE) {
            return FALSE;
        }
        $thisStory["id"] = trim(substr($dataBlock, $startIndex, $endIndex - $startIndex));
        // Adjust the position of the search and parse the story title.
        $startIndex = $endIndex + strlen($searchQueryEnd);
        $endIndex = strpos($dataBlock, $searchQueryTitleEnd, $startIndex);
        if ($endIndex === FALSE) {
            return FALSE;
        }
        $thisStory["title"] = trim(substr($dataBlock, $startIndex, $endIndex - $startIndex));
        // Add the story data to the result array.
        $storyData[] = $thisStory;
        // Reset the search for the next story item.
        $startIndex = strpos($dataBlock, $searchQueryStart, $endIndex + strlen($searchQueryTitleEnd));
    }
    return $storyData;
}

/**
 *	DESCRIPTION:	Returns the title and body of a story from the current issue of the Wildcat Newswire given a story ID value.
 **/
function getStory($storyID) {
    global $NEWSWIRE_URL, $HEADER_DATA;

    // Set up Snoopy with the required parameters.
    $newswire = new Snoopy;
    $newswire -> rawheaders = $HEADER_DATA;

    if ($newswire -> fetch($NEWSWIRE_URL)) {
        $searchQueryStart = '<a name="' . $storyID . '"></a>';
        $searchQueryEnd = '<div class="backtotop">';
        $startIndex = strpos($newswire -> results, $searchQueryStart);
        if ($startIndex === FALSE) {
            // The story ID could not be found.
            return FALSE;
        } else {
            $startIndex += strlen($searchQueryStart);
            $endIndex = strpos($newswire -> results, $searchQueryEnd, $startIndex);
            $dataBlock = trim(substr($newswire -> results, $startIndex, $endIndex - $startIndex));
        }
    } else {
        // Downloading the remote page failed, return FALSE.
        return FALSE;
    }

    $story = array();
    // Extract the story title from the data block.
    $searchQueryStart = '<b>';
    $searchQueryStoryStart = '</div>';
    $searchQueryEnd = '</b>';
    $startIndex = strpos($dataBlock, $searchQueryStart) + strlen($searchQueryStart);
    if ($startIndex === FALSE) {
        // The story title could not be found.
        return FALSE;
    } else {
        $endIndex = strpos($dataBlock, $searchQueryEnd, $startIndex);
        $story["title"] = trim(substr($dataBlock, $startIndex, $endIndex - $startIndex));
        // Extract the HTML body of the story.
        $startIndex = strpos($dataBlock, $searchQueryStoryStart) + strlen($searchQueryStoryStart);
        if ($startIndex === FALSE) {
            return FALSE;
        }
        // Extract and strip the HTML from the story body.
        $story["body"] = trim($newswire -> _striptext(substr($dataBlock, $startIndex)));
    }
    return $story;
}
?>